<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>广开试题</title>
    <style>
      body,
      html {
        height: 100%;
        margin: 0;
        overflow: hidden;
      }

      #app {
        height: 100%;
        overflow: hidden;
        display: flex;
        flex-direction: column;
        margin: 0 10px;
      }

      select {
        height: 30px;
        width: 200px;
        margin-top: 10px;
      }
      .searchInput {
        margin-top: 14px;
        height: 36px;
      }

      .content {
        flex: 1;
        height: 0;
        position: relative;
      }

      .results {
        height: 100%;
        overflow-y: auto;
        white-space: pre-wrap;
        margin-top: 10px;
        background-color: white;
      }
      .result {
        padding-bottom: 10px;
        margin-bottom: 10px;
        border-bottom: 3px solid blue;
        cursor: pointer;
      }

      .textPane {
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        left: 0;
        background-color: white;
      }

      .text {
        height: 100%;
        overflow-y: auto;
        white-space: pre-wrap;
        flex: 1;
      }

      .closeBtn {
        position: absolute;
        top: 6px;
        right: 29px;
        padding: 0 8px;
        cursor: pointer;
        border-radius: 9px;
        font-size: 30px;
        color: red;
        background-color: rgba(0, 0, 0, 0.3);
      }

      font[yellow] {
        background-color: yellow;
      }
      font[coral] {
        background-color: springgreen;
      }

      font[sc] {
        background-color: yellow;
      }
    </style>
  </head>

  <body>
    <div id="app">
      <select v-model="courseName" @change="select(courseName)">
        <option :value="name" v-for="(name,index) in courseNames">
          {{name}}
        </option>
      </select>
      <input
        v-model="searchValue"
        type="search"
        class="searchInput"
        @keyup.enter="doSearch"
      />
      <div v-show="hint">{{hint}}</div>

      <div class="content">
        <div class="results">
          <div
            v-for="(item,index) in results"
            class="result"
            v-html="item.text"
            @click="dbClickResult(item)"
          ></div>
        </div>

        <div class="textPane" v-show="allTextShow">
          <div class="closeBtn" @click="allTextShow=false">X</div>
          <div id="text" class="text" v-html="text"></div>
        </div>
      </div>
    </div>

    <script>
      const courseNames = [
        "跨境电商实务英语",
        "跨文化商务沟通",
        "岭南文化概论",
        "毛泽东思想和中国特色社会主义理论体系概论(A)",
        "商务翻译实务",
        "商务英语写作",
        "市场营销",
        "外贸B2B平台营销",
        "外贸B2C平台营销",
        "艺pp术ppp欣pp赏".replaceAll("p", ""), //卧槽，gitee居然说艺术欣赏违规
      ];

      const vm = {
        el: "#app",
        data: {
          courseNames,
          courseName: "",
          courseMap: {},
          course: {},
          text: "",
          allTextShow: false,
          searchValue: "",
          results: [],
          hint: "",
        },
        created() {
          const that = this;
          this.scheme = new Scheme();

          for (const name of courseNames) {
            let obj = window["course_" + name];
            if (typeof obj === "string") {
              obj = {
                text: obj,
                start: ["\n题目"],
                end: ["\n题目"],
              };
            }
            obj.text = replaceSpace(obj.text);
            this.courseMap[name] = obj;
          }

          this.select(localStorage.getItem("courseName") || courseNames[0]);

          console.log("...created");
          console.log(this.courseMap);

          window.addEventListener(
            "message",
            (event) => {
              const data = event.data || {};
              if (data.dk_course) {
                that.searchValue = data.searchValue;
                that.doSearch();
              }
            },
            false
          );
        },
        methods: {
          select(name) {
            const obj = this.courseMap[name];
            if (typeof obj === "string") {
              this.course = {
                text: obj,
                start: ["\n题目"],
                end: ["\n题目"],
              };
            } else {
              this.course = {
                ...obj,
              };
            }
            this.text = this.course.text;
            this.doSearch();

            this.courseName = name;
            localStorage.setItem("courseName", name);

            console.log("select: " + name);
            console.log(localStorage.getItem("courseName"));
          },
          dbClickResult(resultInfo) {
            console.log("KKK 1", resultInfo);
            this.dbResultCount = (this.dbResultCount || 0) + 1;
            if (this.dbResultCount === 2) {
              this.allTextShow = true;
              this.$nextTick(() => this.scrollTo(resultInfo));
            }
            setTimeout(() => {
              this.dbResultCount = 0;
            }, 500);
          },
          scrollTo(resultInfo) {
            console.log("KKK 2", resultInfo);
            if (!resultInfo) return;

            console.log("scrollTo", resultInfo);

            const childElement = document.querySelector(
              "#sc_" + resultInfo.count
            ); // 获取子元素
            console.log(childElement);
            childElement.scrollIntoView(); // 滚动到子元素位置
          },
          doSearch() {
            let searchValue = this.searchValue;
            if (searchValue.length < 3) {
              console.warn("最少需要3个字符");
              return;
            }
            this.scheme.refresh(() => {
              this.flxSearchResule(searchValue);
            });
          },
          flxSearchResule(searchValue) {
            console.log("doSearch: ", searchValue);

            this.results = [];
            if (!searchValue) {
              this.text = this.course.text;
              return;
            }

            //去除前后空格
            searchValue = searchValue.trim();
            // //去除标点符号
            // searchValue = searchValue.replace(/\s/g, "");
            // //去除标点符号
            // searchValue = searchValue.replace(/[\p{P}]/gu, "");

            let text = "";
            let svLen = searchValue.length;
            let sIdx = -1;
            let startIdx = 0;
            let count = 0;

            while (
              (sIdx = this.course.text.indexOf(searchValue, startIdx)) >= 0
            ) {
              text +=
                this.course.text.substring(startIdx, sIdx) +
                `<font sc id='sc_${count}'>${searchValue}</font>`;

              this.results[count] = this.getResult(count, sIdx, searchValue);
              count++;
              startIdx = sIdx + svLen;
            }
            if (this.results.length === 0) {
              this.hint =
                "搜索：" +
                searchValue +
                "，  没有搜索到内容-" +
                (new Date().getTime() % 1000);
            } else {
              this.hint =
                "搜索：" + searchValue + " (" + this.results.length + ")";
            }

            text += this.course.text.substr(startIdx);
            text = text.replaceAll("答案", "<font coral>答案</font>");
            this.text = text;
          },
          getResult(count, sIdx, searchValue) {
            let svLen = searchValue.length;
            let textLen = this.course.text.length;
            const { startMax, endMax, endAdd } = this.course;

            let start = -1;
            for (let s of this.course.start) {
              start = this.course.text.lastIndexOf(s, sIdx);
              if (start >= 0) break;
            }
            if (start < 0) start = 0;
            if (startMax && sIdx - start > startMax) start = sIdx - startMax;

            let end = -1;
            for (let s of this.course.end) {
              end = this.course.text.indexOf(s, sIdx);
              if (end >= 0) break;
            }
            if (end < 0) end = textLen;
            if (endMax && end - sIdx > endMax) end = sIdx + endMax;
            if (endAdd) end = end + endAdd;

            let text =
              this.course.text.substring(start, sIdx) +
              `<font sc>${searchValue}</font>` +
              this.course.text.substring(sIdx + svLen, end);
            text = text.replaceAll("答案", "<font coral>答案</font>");
            text = text.trim();

            return {
              count: count,
              text,
            };
          },
        },
      };

      let initCount = 1;

      let jsDoc = "";
      for (const name of courseNames) {
        const _script = document.createElement("script");
        _script.src = "./course/" + name + ".js";
        _script.onload = () => tryInit();
        document.body.append(_script);
        initCount++;
      }

      function tryInit() {
        if (--initCount !== 0) return;
        console.log("Vue load...");
        new Vue(vm);
      }

      function fixNum(val) {
        if (typeof val === "string") {
          let idx = val.indexOf("/");
          if (idx >= 0) val = val.substr(0, idx);
          if (!isNaN(Number(val))) val = Number(val);
        }
        return val;
      }

      function replaceSpace(str) {
        if (!str) return str;
        str = str.replace(/\n/g, "@-n");
        str = str.replace(/\s/g, " ");
        str = str.replace(/@-n/g, "\n");
        return str;
      }

      class Scheme {
        constructor() {
          this.runing = false;
        }
        refresh(fun) {
          this.waitFun = fun;
          this.tryRun();
        }
        tryRun() {
          if (this.waitFun && !this.runing) {
            this.runing = true;
            [this.waitFun, (this.waitFun = null)][0]();
            setTimeout(() => {
              this.runing = false;
              this.tryRun();
            }, 100);
          }
        }
      }

      // function escapeRegExp(string) {
      //   return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // 转义特殊字符
      // }

      // function buildRegex(pattern) {
      //   const escapedPattern = escapeRegExp(pattern);
      //   return new RegExp(escapedPattern, "g");
      // }

      // const searchTerm = 'Hello World!';
      // const dynamicRegex = buildRegex(searchTerm);

      // const text = 'Hello World! It is a beautiful world.';
      // const matches = text.match(dynamicRegex);
      // console.log(matches); // 输出: ["Hello World!"]
    </script>

    <script
      src="https://cdn.staticfile.org/vue/2.7.0/vue.min.js"
      onload="tryInit()"
    ></script>
  </body>
</html>
